#include "wds_bullet_collection.h"
#include "wds_bullet_rocket.h"
#include "wds_rocket_seeker.h"
#include "wds_sounds.h"
#include "wds_bullet_sfx.h"
#include "wds_bullet_plasmacannon.h"
#include "wds_bullet_flame.h"
#include "wds_bullet_ion.h"

#include "num/rand.h"
#include "math/facing.h"
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    
#include <cassert>


WDSBulletCollection::WDSBulletCollection(WDSBullet::BULLET_TYPES Type) : 
										m_Type(Type)
{
	
}


	



void			WDSBulletCollection::Render( const math::Vec2& Offset,float Scale)
{
	for(unsigned int i = 0; i < m_Bullets.size(); i++)
	{
		WDSBullet*  Bullet = m_Bullets[i];
		Bullet->Render(Offset,Scale);
	}
}

void			WDSBulletCollection::RenderDebug(const math::Vec2& Offset, float Scale)
{
	for(unsigned int i = 0; i < m_Bullets.size(); i++)
	{
		WDSBullet*  Bullet = m_Bullets[i];
		Bullet->RenderDebug(Offset,Scale);
	}
}

void			WDSBulletCollection::Tick(float dt, float SkillBulletSpeed, const math::Vec2& Offset)
{
	for(unsigned int i = 0; i < m_Bullets.size(); i++)
	{
		WDSBullet*  pBullet = m_Bullets[i];
		pBullet->Tick(dt,SkillBulletSpeed, Offset);		
	}

	
}

WDSBullet*		WDSBulletCollection::Shoot(	WDSLifeObject* pShooter,
											const math::Vec2& ShootPos,										
											float Degree,																													
											int SoundSFXIndex)
{
	
	WDSBullet* pBullet = NULL;
	math::Vec2 Pos = ShootPos;
	
	WDSSounds::Instance().PlaySoundSFX((WDSSounds::SOUND_NAMES)SoundSFXIndex);
	pBullet	= Spawn(  
					pShooter,
					Pos, 
					WDSBullet::STARTPOS_MIDDLE,
					Degree									
					);
	

	return pBullet;
	
}



void		WDSBulletCollection::Clear()
{
	for(unsigned int i = 0; i < m_Bullets.size(); i++)
	{
		WDSBullet*  Bullet = m_Bullets[i];
		Bullet->Clear();
	}
	
	
	for( int i = (int)m_Bullets.size() - 1; i >= 0; i--)
	{
		WDSBullet*  pBullet = m_Bullets[i];
		UTIL_SAFE_DELETE(pBullet);
	}
	m_Bullets.resize(0);
}

void			WDSBulletCollection::DieAll()
{
	for(unsigned int i = 0; i < m_Bullets.size(); i++)
	{
		WDSBullet*  Bullet = m_Bullets[i];
		Bullet->Kill();
	}
}

WDSBullet*			WDSBulletCollection::Spawn(
										WDSLifeObject*	pShooter,
										const math::Vec2& Pos,
										WDSBullet::STARTPOS StartDir,
										float Degree										
										)
{

	for( int i = 0; i < (int)m_Bullets.size(); i++)
	{
		WDSBullet*  Bullet = m_Bullets[i];
		if(Bullet->IsCanRespawn())
		{
			Bullet->ReSpawn(Pos, StartDir, Degree);
			return Bullet;
		}
	}

	WDSBullet* pBullet = NULL;

	
	const float P_N_POWER = 1.0f;
	const float P_R_POWER = 10.0f;
	const float P_H_POWER = 6.0f;
								 
	const float E_POWER_1 = 1.0f;
	const float E_POWER_2 = 2.0f;

	
	switch(m_Type)
	{
		case WDSBullet::BULLET_TYPE_NORMAL:
			pBullet = new WDSBullet(1.0f,
									false,
									P_N_POWER + ( P_N_POWER * 0.3f),
									m_Type);			
			if(pBullet)
				pBullet->SetLeaveAlphaTrial(true);
		break;

		case WDSBullet::BULLET_TYPE_FIRE:
			pBullet = new WDSBullet(1.0f,
									false,
									P_N_POWER + ( P_N_POWER * 0.3f),
									m_Type);			
			if(pBullet)
			{
				pBullet->SetLeaveAlphaTrial(true);
				pBullet->SetIsTypeGauss(true);
			}
		break;

		case WDSBullet::BULLET_TYPE_GAUSS:
			pBullet = new WDSBullet(4.0f,
									false,
									P_N_POWER + ( P_N_POWER * 0.3f),
									m_Type);	
			pBullet->SetIsTypeGauss(true);
			if(pBullet)
				pBullet->SetLeaveAlphaTrial(true);
		break;

		case WDSBullet::BULLET_TYPE_PLASMA:
			pBullet = new WDSBullet(1.0f,
								false,
								P_N_POWER + ( P_N_POWER * 0.3f),
								m_Type);			
		break;
		
		case WDSBullet::BULLET_TYPE_PLASMACANNON:
			pBullet = new WDSBulletPlasmaCannon();
		break;

		case WDSBullet::BULLET_TYPE_ROCKET:
			pBullet = new WDSBulletRocket(1.0f,false);
		break;

		case WDSBullet::BULLET_TYPE_HOMINGROCKET:
			pBullet = new WDSRocketSeeker(1.0f);
		break;

		case WDSBullet::BULLET_TYPE_PULSE:
			pBullet = new WDSBullet(1.0f,
								false,
								P_N_POWER + ( P_N_POWER * 0.3f),
								m_Type);	
		break;

		case WDSBullet::BULLET_TYPE_FLAME:
			pBullet = new WDSBulletFlame(0.25f,WDSSfx::SFX_BULLET_FLAME);
		break;

		case WDSBullet::BULLET_TYPE_ION:
			pBullet = new WDSBulletION(1.0f,
									false,
									1.0f,
									m_Type);
		break;

	

		default:
			break;
	}

	if(pBullet)
	{
		std::string SpriteName = WDSBullet::GetSpriteNameByType(m_Type);
		if(!SpriteName.empty())
			pBullet->Load(SpriteName);
		m_Bullets.push_back(pBullet);
		pBullet->ReSpawn(Pos, StartDir ,Degree);
		return pBullet;
	}

	

	return NULL;
	
	
}


int			WDSBulletCollection::GetCount() const
{
	return (int)m_Bullets.size();
}

WDSBullet*	WDSBulletCollection::GetBulletByIndex(int Index)
{
	return m_Bullets[Index];
	
}



WDSBullet*	WDSBulletCollection::ShootToDegree(WDSLifeObject* pShooter, const math::Vec2& Pos, float Degree)
{
	if(Degree > 360)
		Degree = Degree - 360;

	//return Spawn(pShooter, Pos,WDSBullet::STARTPOS_MIDDLE , Degree);
	return NULL;
}


void	WDSBulletCollection::ShootToAllDir(const math::Vec2& Pos)
{
	int Degree = 0;
	while(Degree <= 360)
	{
		WDSBullet* pBullet = ShootToDegree(NULL, Pos,(float)Degree);
		Degree += 45;

		
	}
	

}
